using System.Net.Http.Headers;
using FileTransfer.Client.Http.Api;
using FileTransfer.Client.Http.Client;

namespace FileTransfer.Client;

public class ApiClient : IDisposable
{
    public delegate void AddHeadersDelegate(HttpRequestMessage request);

    public class HttpWithHeadersClientHandler(AddHeadersDelegate addHeaders) : HttpClientHandler
    {
        protected override HttpResponseMessage Send(
            HttpRequestMessage request,
            CancellationToken cancellationToken
        )
        {
            addHeaders(request);
            return base.Send(request, cancellationToken);
        }

        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken
        )
        {
            addHeaders(request);
            return base.SendAsync(request, cancellationToken);
        }
    }

    public ApiClient(Configuration? config, Func<string?>? getAuthToken)
    {
        var httpClientHandler = new HttpWithHeadersClientHandler(request =>
        {
            if (getAuthToken is { })
            {
                var authToken = getAuthToken();
                if (!string.IsNullOrEmpty(authToken))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue(
                        "Bearer",
                        authToken
                    );
                }
            }
        });
        var httpClient = new HttpClient(httpClientHandler);
        config ??= new Configuration();
        FileControllerApi = new FileControllerApi(httpClient, config, httpClientHandler);
        ShareItemControllerApi = new ShareItemControllerApi(httpClient, config, httpClientHandler);
        MessageControllerApi = new MessageControllerApi(httpClient, config, httpClientHandler);
        StatisticControllerApi = new StatisticControllerApi(httpClient, config, httpClientHandler);
        ConnectionControllerApi = new ConnectionControllerApi(
            httpClient,
            config,
            httpClientHandler
        );
        UserControllerApi = new UserControllerApi(httpClient, config, httpClientHandler);
        AvatarControllerApi = new AvatarControllerApi(httpClient, config, httpClientHandler);
    }

    public FileControllerApi FileControllerApi { get; init; }
    public ShareItemControllerApi ShareItemControllerApi { get; init; }
    public MessageControllerApi MessageControllerApi { get; init; }
    public StatisticControllerApi StatisticControllerApi { get; init; }
    public ConnectionControllerApi ConnectionControllerApi { get; init; }
    public UserControllerApi UserControllerApi { get; init; }
    public AvatarControllerApi AvatarControllerApi { get; init; }

    public void Dispose()
    {
        FileControllerApi.Dispose();
        ShareItemControllerApi.Dispose();
        MessageControllerApi.Dispose();
        StatisticControllerApi.Dispose();
        ConnectionControllerApi.Dispose();
        UserControllerApi.Dispose();
    }
}

public static class ApiHelper
{
    public static ApiClient NewApiClient(Configuration? config, Func<string?>? getAuthToken = null)
    {
        return new ApiClient(config, getAuthToken);
    }
}
